#include "networkessential.h"
#include "singleMember.h"
#include "messageBase.h"
#include "common.h"

bool sendMessageBySocket(const messageBase *message, SOCKET sock)
{
	std::string messageData = message->getData();
	int messageLength = messageData.size();
	return sendData(sock, messageData.c_str(), messageLength);
}

bool sendMessageByNetAddr(const messageBase *message, struct sockaddr_in netaddr)
{
	SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
	bool retval;
	std::string messageData = message->getData();
	int messageLength = messageData.size();

	char char_message_data[512] = {0};
	memcpy(char_message_data, messageData.c_str(), messageLength);

	retval = sendDataTo(sock, char_message_data, 512,
		(struct sockaddr *) &netaddr, sizeof(netaddr));

	closesocket(sock);
	return retval;
}

bool sendMessageToMember_tcp(const messageBase *message, const singleMember *member)
{
	return sendMessageBySocket(message, member->getSock());
}

bool sendMessageToMember_udp(const messageBase *message, const singleMember *member)
{
	sockaddr_in addr;
	addr.sin_addr.S_un.S_addr = htonl(member->getNetAddr());
	addr.sin_family = AF_INET;
	addr.sin_port   = htons(UDPRecvPort);
	return sendMessageByNetAddr(message, addr);
}

bool broadcastMessage(const messageBase *message)
{
	bool on = 1;
	SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
	
	int sendedLength;
	
	// Generate broadcast address
	struct sockaddr_in bcaddr;
	bcaddr.sin_family = AF_INET;
	bcaddr.sin_port = htons(UDPRecvPort);
	bcaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);

	setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof(on));
	std::string messageData = message->getData();
	int messageLength = messageData.size();

	char char_message_data[512] = {0};
	memcpy(char_message_data, messageData.c_str(), messageLength);
	sendedLength = sendto(sock, char_message_data, 
		512, 0, (sockaddr *) &bcaddr, sizeof(bcaddr));

	closesocket(sock);

	if (sendedLength <= 0)
		return false;

	return true;
}
